import request from "../framework/common/utils/request";
import isUndefined from "lodash/isUndefined";
import { applyRule } from "../framework/common/rule/rule";
import {mergecalculateFormData} from "./mergeFormData";
import message from "../framework/common/utils/message";
import { getPrintHideInfo, getQuery } from "../framework/common/utils";
import set from "lodash/set";
import get from "lodash/get";
import { getCalculationFields } from "./mergeData";

let buildFormData = {
  mergeFormData: function (tplDataForm) {
    //加载时处理数据
    var self = this;
    var data_control = tplDataForm.data_control;
    var form_data = tplDataForm.form_data;
    var form_layout = JSON.parse(tplDataForm.form_meta_data);
    var form_define = tplDataForm.data_define;
    
    //遍历业务对象，把字段步骤权限拼接到业务对象上
    //1.处理主表
    form_define.main.fields.forEach(function (field) {
      let fieldCode = field.code;
      //遍历主表步骤权限
      data_control.main.fields.find(function(controlField){
        let controlFieldCode = controlField.code;
        if (fieldCode === controlFieldCode) {
          //根据业务对象字段code匹配步骤权限内字段
          field.is_editable = controlField.is_editable; //步骤is_editable权限给到业务对象字段
          return true;
        }
      });
    });
    //2.处理子表
    //遍历业务对象子表分组
    form_define.children.forEach(function(group){
      let groupCode = group.code;
      //遍历业务对象子表字段
      group.fields.forEach(function (field) {
        let fieldCode = field.code;
        //遍历步骤权限子表分组
        data_control.children.forEach(function(controlGroup){
          let controlGroupCode = controlGroup.code;
          if(groupCode === controlGroupCode){
            //遍历步骤权限子表字段
            controlGroup.fields.find(function(controlField){
              let controlFieldCode = controlField.code;
              if (fieldCode === controlFieldCode) {
                //根据业务对象字段code匹配步骤权限内字段
                field.is_editable = controlField.is_editable; //步骤is_editable权限给到业务对象字段
                return true;
              }
            });
          }
        });
      });
    });

    //this.phpIllegalNumberCompatible(form_define,tplDataForm);//兼容php二逼数据
    //注释的这个方法，需要处理php数值类型为 0.06 会，实际返回成 .06的情况，

    form_layout = self.mergeTheUncoveredFieldsToForm(form_define, form_layout);
    var meta_data = self.merge_form_layout_define(form_layout, form_define);
    var valSet = self.getValSet(form_data);
    var ctlSet = self.getCtlSet(data_control);
    var dftValCfg = self.getDftvalSet(form_data.defaultValueConf);
    var data = { ...meta_data }; 
    for (var ig = 0; ig < data.groups.length; ig++) {
      var group = data.groups[ig];
      //普通分组
      if (!group.isSubTable) {
        for (var ir = 0; ir < group.rows.length; ir++) {
          var row = group.rows[ir];
          for (var ic = 0; ic < row.cols.length; ic++) {
            var col = row.cols[ic];
            if (col.data.length == 0) continue;
            var _code = col.data[0].code;
            if (ctlSet["main"].hasOwnProperty(_code)) {
            
              col.data[0] = { ...col.data[0], ...ctlSet["main"][_code] };
              if (ctlSet["main"][_code]) {
                ctlSet["main"][_code].type = col.data[0]?.type; //后端在form data reload接口需要type数据找文件类型 不然就报错
              }

              //数值类型
              if(ctlSet["main"][_code].type == "number"){
                let handle_null_value = col.data[0]?.props?.handle_null_value;
                let defaultValue = get(form_data, "main." + _code);//获得默认值
                if (defaultValue === null || defaultValue === undefined || defaultValue === "") {//默认值不存在
                  if (handle_null_value != "show_null") {//数值字段配置了“为空时显示为0”
                    // set(form_data, "main." + _code, 0);//更新 tpldata 数据源这个字段为0，否则计算会拿空置对比，导致计算不准
                  } 
                }
              }
            } else {
              col.data[0].is_show = false;
              col.data[0].is_editable = false;
              col.data[0].is_required = false;
            }
            if (dftValCfg["main"].hasOwnProperty(_code)) {
              col.data[0]["default"] = dftValCfg["main"][_code];//给字段配置默认值
            }
            //tip类型在data control里面有时候会丢失
            if(col.data[0].type==="tip"&&col.data[0].is_show===undefined){
              col.data[0].is_show=false;
            }
          }
        }
      } else {
        //子列表分组
        var columns = [];
        var rows = [];
        var tName = group.code; //表名
        var isHasObjId = false;
        //先处理列头数据
        for (var ifd = 0; ifd < group.fields.length; ifd++) {
          var field = group.fields[ifd];
          var column = { ...field };
          var fcode = field.code;
          if (field.type == "subTableSid") {
            column.is_show = true;
          }
          if (ctlSet["children"][tName]) {
            if (ctlSet["children"][tName][fcode]) {
              column = { ...column, ...ctlSet["children"][tName][fcode] };
            } else if (column.type !== "subTableSid") {
              //后端bug 同步过来的字段data control里面没数据
              column.is_show = false;
              column.is_editable = false;
              column.is_required = false;
            }
           
          }
         
          if (!column.designProps) column.designProps = {};
          column.designProps.layout = "control_layout_column";

          if (dftValCfg["children"][tName] && dftValCfg["children"][tName][fcode]) {
            column["default"] = dftValCfg["children"][tName][fcode];
          }
          if (field.code == "obj_id") {
            isHasObjId = true;
          }
          columns.push(column);
        }
        if (!isHasObjId) {
          columns.push({
            code: "obj_id",
            designProps: { layout: "control_layout_column" },
            isShow: true,
            is_editable: true,
            is_show: true,
            is_sys: 1,
            name: "子表业务键ID",
            props: [],
            range: undefined,
            style: {},
            type: "uuid",
          });
        }
        //再处理数据行 生成子表的行数据
        if (valSet["children"][tName] && valSet["children"][tName].length > 0) {
          var valRows = valSet["children"][tName];
          for (var ir = 0; ir < valRows.length; ir++) {
            var valRow = valRows[ir];
            var row = [];
            for (var ic = 0; ic < columns.length; ic++) {
              var column = columns[ic];
              if(column.type == "number"){
                let handle_null_value = column.props?.handle_null_value;
                if (handle_null_value != "show_null") {//数值字段配置了“为空时显示为0”
                  let defaultValue = valRow[column.code];//获得默认值
                  if (defaultValue === null || defaultValue === undefined || defaultValue === "") {//默认值不存在
                    // valRow[column.code] = 0;//更新 tpldata 数据源这个字段为0，否则计算会拿空置对比，导致计算不准
                  }
                }
              }
              //每个数据单元就是复制设计时列的结构+值
              var field = { ...column }; 
              field.value = self.isSet(valRow[column.code]) ? valRow[column.code] : null; //设置单元格默认值
              if (!isUndefined(valRow.rowLevel)) {
                field.rowLevel = valRow.rowLevel;
              }
              delete field.rowspan; //数据部分不需要rowspan属性，只有子表头部需要做多行头合并用到
              row.push(field);
            }
            rows.push(row); //生成行数据
          }
        }
        if (typeof ctlSet["children"][tName] === "undefined") {
          group.isAdd = true;
          group.isDelete = true;
        } else {
          group.isAdd = ctlSet["children"][tName].is_add;
          group.isDelete = ctlSet["children"][tName].is_delete;
        }
        group.columns = columns;
        group.rows = rows;
      }
    }
    return data;
  },
  mergeObj: function (obj1, obj2, exclude, isCover) {
    if (!obj2) return obj1;
    var cover = false;
    if (!exclude) exclude = [];
    if (isCover == true) cover = true;
    for (var k2 in obj2) {
      var has = false;
      if (!cover) {
        for (var k1 in obj1) {
          if (k2 == k1) has = true;
        }
      }
      if (!has && exclude.indexOf(k2) == -1) {
        if (typeof obj2[k2] == "object") {
          obj1[k2] = JSON.parse(JSON.stringify(obj2[k2]));
        } else {
          obj1[k2] = obj2[k2];
        }
      }
    }
    return obj1;
  },
  isSet: function (val) {
    return !(typeof val == "undefined" || val == null || val === "");
  },
  getValSet: function (form_data) {
    var set = {};
    set.main = {};
    set.children = {};
    if (form_data) {
      if (form_data.main) {
        for (var key in form_data.main) {
          set.main[key] = form_data.main[key];
        }
      }
      if (form_data.children) {
        // children的数据结构是这样的，所以不用再做多余的组合
        // children:{"subTable1":[{"field1":"value1","field2":"value2"},{"field1":"value1",...}]}
        set.children = { ...form_data.children }; 
      }
    }
    return set;
  },
  getCtlSet: function (data_control) {
    var set = {};
    set.main = {};
    set.children = {};
    if (data_control) {
      if (data_control.main) {
        for (var ifield = 0; ifield < data_control.main.fields.length; ifield++) {
          var field = data_control.main.fields[ifield];
          set.main[field.code] = field;
        }
      }
      if (data_control.children) {
        for (var ichild = 0; ichild < data_control.children.length; ichild++) {
          var child = data_control.children[ichild];
          set.children[child.code] = {
            is_add: typeof child.is_add === "undefined" ? true : child.is_add,
            is_delete: typeof child.is_delete === "undefined" ? true : child.is_delete,
          };
          for (var ifield = 0; ifield < child.fields.length; ifield++) {
            var field = child.fields[ifield];
            set.children[child.code][field.code] = field;
          }
        }
      }
    }
    return set;
  },
  getDftvalSet: function (dftValCfg) {
    if (dftValCfg) {
      return { ...dftValCfg }; 
    }
    return {
      main: {},
      children: [],
    };
  },
  mergeTheUncoveredFieldsToForm: function (form_define, form_layout) {
    var layout = { ...form_layout }; 
    var cols_tmpl = [];
    form_define.main.fields.forEach(function (field) {
      var isExist = false;
      layout.groups.forEach(function (group) {
        if (isExist) return;
        if (!group.isSubTable) {
          group.rows.forEach(function (row) {
            if (isExist) return;
            row.cols.forEach(function (col) {
              if (isExist) return;
              if (col.data.length == 0) return;
              var fCode = col.data[0].code;
              if (fCode === field.code) {
                isExist = true;
                return;
              }
            });
          });
        }
      });
      if (!isExist) {
        cols_tmpl.push({
          data: [{ code: field.code, is_ghost: true }],
        });
      }
    });
    if (cols_tmpl.length > 0) {
      var group_tmpl = { title: "hidden-group", id: "hidden-group", rows: [{ cols: cols_tmpl }], is_ghost: true };
      form_layout.groups.push(group_tmpl);
    }

    form_define.children.forEach(function (child) {
      var isGroupExist = false;
      layout.groups.forEach(function (group) {
        if (group.isSubTable) {
          if (group.code === child.code) {
            isGroupExist = true;
            child.fields.forEach(function (field) {
              var isFieldExsit = false;
              group.fields.forEach(function (fd) {
                if (isFieldExsit) return;
                if (fd.code === field.code) {
                  isFieldExsit = true;
                  return;
                }
              });
              if (!isFieldExsit) {
                var dlGroup = null;
                form_layout.groups.forEach(function (g) {
                  if (g.code === group.code) dlGroup = g;
                });
                dlGroup.fields.push({
                  code: field.code,
                  is_show: true,
                  is_editable: false,
                  is_ghost: true,
                }); //子表列字段没有在表单设计器添加到子表上，也需要追加到子表的列信息上
              }
            });
          }
        }
      });
      if (!isGroupExist) {
        var fields_tmpl = [];
        child.fields.forEach(function (fd) {
          fields_tmpl.push({ code: fd.code, name: fd.name, is_show: true, is_ghost: true });
        });
        var group_tmpl = { isSubTable: true, title: child.name, code: child.code, fields: fields_tmpl, is_ghost: true };
        form_layout.groups.push(group_tmpl);
      }
    });

    return form_layout;
  },
  transDefineToKeyValue: function (data_define) {
    var data = new Object();
    data.main = {};
    data.children = {};
    var define_main = data_define.main;
    var define_children = data_define.children;
    for (var imfd = 0; imfd < define_main.fields.length; imfd++) {
      var mfield = data_define.main.fields[imfd];
      if (mfield) {
        data.main[mfield.code] = mfield;
      }
    }
    for (var ictb = 0; ictb < define_children.length; ictb++) {
      var ctable = define_children[ictb];
      var child = {};
      for (var icfd = 0; icfd < ctable.fields.length; icfd++) {
        var cfield = ctable.fields[icfd];
        if (cfield) {
          child[cfield.code] = cfield;
        }
      }
      data.children[ctable.code] = child;
    }
    data.code = define_main.code;
    return data;
  },
  getSubtabelNotSysFieldsLength: function (group) {
    var count = 0;
    group.fields.forEach(function (field) {
      if (field.is_sys !== 1) count++;
    });
    return count;
  },
  merge_form_layout_define: function (data_layout, data_define) {
    var self = this;
    var transData = self.transDefineToKeyValue(data_define);
    var define_main = transData.main;
    var define_children = transData.children;
    //notExistGroupsIdx,notExistFieldsIdx用来记录业务对象已经删除但表单上还存在的分组和字段的索引，循环结束后需要进行清除
    var notExistGroupsIdx = [];
    for (var ig = 0; ig < data_layout.groups.length; ig++) {
      var group = data_layout.groups[ig];
      if (group.isSubTable == true) {
        var define_table = define_children[group.code];
        if (define_table) {
          // group = mergeObj(group,define_table,["fields"],true);
          var notExistFieldsIdx = [];
          for (var ifd = 0; ifd < group.fields.length; ifd++) {
            var field = group.fields[ifd];
            var define_field = define_table[field.code];
            if (define_field) {
              //合并(覆盖模式)子表字段
              group.fields[ifd] = self.mergeObj(field, define_field, ["isShow"], true);
            } else {
              notExistFieldsIdx.push(ifd);
            }
          }

          if (notExistFieldsIdx.length === self.getSubtabelNotSysFieldsLength(group)) {
            notExistGroupsIdx.push(ig);
          } else {
            notExistFieldsIdx.forEach(function (delIdx) {
              var delItem = group.fields[delIdx];
              if (delItem && delItem.designProps && delItem.designProps.type == "subTableSid") {
                delItem.name = "序号";
                delItem.type = "subTableSid";
                delItem.type_name = "序号";
                if (delItem.style && !delItem.style.minWidth) {
                  delItem.style = { minWidth: 60, width: 60 };
                }
              } else {
                group.fields.splice(delIdx, 1);
              }
            });
          }

          //子表字段定义中新增加了字段，要加到布局上，并默认设为隐藏
          for (var dfkey in define_table) {
            var existInGroup = false;
            group.fields.forEach(function (fd) {
              if (fd.code == dfkey) existInGroup = true;
            });
            if (existInGroup == false) {
              var dfield = self.mergeObj({}, define_table[dfkey]);
              dfield.isShow = false;
              group.fields.push(dfield);
            }
          }
        } else {
          notExistGroupsIdx.push(ig);
        }
      } else {
        for (var irow = 0; irow < group.rows.length; irow++) {
          var row = group.rows[irow];
          for (var icol = 0; icol < row.cols.length; icol++) {
            var col = row.cols[icol];
            if (col.data.length > 0) {
              var data = col.data[0];
              var _define = define_main[data.code];
              if (_define) {
                //合并(覆盖模式)主表字段
                col.data[0] = self.mergeObj(data, _define, [], true);
              } else {
                if (col.data[0] && col.data[0].type == "tip") {
                  //如果是说明文字，不处理
                } else {
                  //其他的清掉data，防止在业务对象删除了字段，但是流程定义还存在记录，导致数据异常
                  col.data = [];
                }
              }
              // else{
              //     col.data = [];
              // }
            }
          }
        }
      }
    }
    notExistGroupsIdx.forEach(function (delIdx) {
      data_layout.groups.splice(delIdx, 1);
    });
    data_layout.code = transData.code;
    return data_layout;
  },
};

/*
  tplData.ProcessInfo.ProcessStatus
  -4 发起
  -3 草稿 
  -2 作废
  -1 终止 
  0 处理中
  1 已通过
  2 已归档
*/

//获取表单数据
export function getApprovalProcessInfo(query, mode) {
  let url = "/flowinstance/process/get-process-info"; //发起
  if (mode === 2) {
    //审批中
    url = "/flowinstance/approval/get-process-info";
  }
  else if(mode ===3) //打印页
  {
    url =  "/flowinstance/approval/get-process-preview"
  }
  return request({
    url: url + query,
    method: "get",
  }).then(
    function (data) {
      if (data?.data?.status === 302) {
        //返回值status为302时
        window.location = data.data.location; //跳转到后端给定的链接
        return;
      }

      if (data.data) {
        //设置流程状态标记
        let _tplData = data.data.tplData;
        var flowStatus = null;
        if (!_tplData?.ProcessInfo?.ProcessGuid) {
          flowStatus = "start";
      } 
      if(_tplData?.ProcessInfo?.ProcessStatus == -3) {
        flowStatus = "draft";
      }
      if(_tplData.ProcessInfo.ProcessStatus == -4) {
        flowStatus = "start";
      }
      if(_tplData?.StepInfo?.step_type == 1 && _tplData?.form_readonly == false){
          if(_tplData?.ProcessInfo?.ProcessStatus == 0){
              flowStatus = "restart";
          }
      }
      _tplData.__flowStatus__ = flowStatus;//前端打上流程状态标记

      //后端存的是字符串，转换成JSON对象
      window.csrfToken = data.data.csrfToken;//临时存一个全局变量，给老页面嵌套的iframe使用，后续重构完之后，需要删除这个变量
      window.urlPrefix = data.data.urlPrefix;//存储一个全局 urlPrefix，用于拦截请求，给url拼接前缀

      // 获取是否是重载的页面
      
      let is_reload = getQuery().is_reload; //url参数是否包含是否重新加载
      if (data.data.tplData.form.is_new_form && is_reload != "1") {
        message.info({
          content: "流程已发布新表单，将重置当前页面。<br />重置后，若表单中有可编辑信息请重新填写。",
        });
      }else if(data.data.tplData.businessObjectException != null){
        message.info({
          content: data.data.tplData.businessObjectException,
        });
      }
      
      if(data.data.tplData.form.form_mode == 0){//流程中心表单
        var formSource = buildFormData.mergeFormData(data.data.tplData.form);//初始化数据清洗
        data.data.tplData.__calculationFields__ = getCalculationFields({
          tplData: data.data.tplData
        });//缓存所有计算字段code，form-data-reload时，排除计算字段的数据覆盖
        data.data.tplData.form.form_meta_data = formSource; //JSON.parse(data.data.tplData.form.form_meta_data);
        data.data.tplData.originRulesStr = data.data.tplData.form.form_rules; //存储原始的form rules字符串
        data.data.tplData.form.form_rules = JSON.parse(data.data.tplData.form.form_rules);
        data.data.tplData.calculateFormData = mergecalculateFormData(data.data.tplData);//计算类型数据清洗，用于生成参与计算时的数据
        data.data.tplData.form.form_style_data = JSON.parse(data.data.tplData.form.form_style_data);
      }else{
        //data.data.tplData.form.form_mode=1定制表单

      }

      //fixme : mock tplData.hideInfo
      //fixme: 如果是打印模式，需要初始化这个结构
      if(Array.isArray(data.data.tplData.hideInfo) && data.data.tplData.hideInfo.length==0 || !data.data.tplData?.hideInfo){
        
        data.data.tplData.hideInfo = getPrintHideInfo({
          tplData: _tplData
        });
        
      }
     
      data.data.tplData.hideTrackingInfo = new Set()

      window.tplData = data.data.tplData;//绑定tplData到window上，有其他地方会依赖

      //把formTitleBar放到tplData中
      data.data.tplData.formTitleBar = data.data.formTitleBar;

      if(data.data.tplData.form.form_mode == 0){//流程中心表单
        applyRule(data.data.tplData);//条件规则隐藏
      }
      return Promise.resolve(data);
    }
  },function(error){
    if(error?.code===undefined || error?.code==="ERR_BAD_RESPONSE")
      message.info({
        content: "加载表单失败",
      });
  });
}